home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / UTIL / Alpha 6.5.sit / Tcl / Modes / htmlElems.tcl < prev    next >
Text File  |  1996-08-15  |  25KB  |  920 lines

  1. #===============================================================================
  2. #    htmlElems.tcl (called by html.tcl)
  3. #
  4. #    Part of HTML mode 1.2
  5. #
  6. #    Macros for HTML elements.
  7. #
  8. #    Author: Johan Linde <jl@theophys.kth.se>
  9. #
  10. #    If you make improvements to this file, please share them!
  11. #
  12. #===============================================================================
  13.  
  14.  
  15. #
  16. # <P>
  17. #
  18.  
  19. proc htmlElemParagraph {{attr ""}} {
  20.     global HTMLmodeVars
  21.     set pIsContainer    $HTMLmodeVars(pIsContainer)
  22.     
  23.     if ($pIsContainer) { 
  24.         htmlBuildCR2Elem P $attr
  25.     } else {
  26.         htmlBuildOpening P 1 1 $attr
  27.     }
  28. }
  29.  
  30.  
  31. # Insert a <BR> in the end of every line in selection.
  32.  
  33. proc htmlInsertLineBreaks {} {
  34.     if {![isSelection]} {
  35.         beep
  36.         message "No selection."
  37.         return
  38.     }
  39.     
  40.     foreach ln [split [string trimright [getSelect] "¥r"] "¥r"] {
  41.         append text "${ln}[htmlSetCase <BR>]¥r"
  42.     }
  43.     replaceText [getPos] [selEnd] $text
  44. }
  45.  
  46. # Remove all <BR> in selection.
  47. proc htmlRemoveLineBreaks {} {
  48.     if {![isSelection]} {
  49.         beep
  50.         message "No selection."
  51.         return
  52.     }
  53.     
  54.     regsub -all "<(b|B)(r|R)(¥[ ¥t¥r¥]+¥[^>¥]*>|>)" [getSelect] "" text
  55.     if {$text != [getSelect]} {
  56.         replaceText [getPos] [selEnd] $text
  57.     }
  58. }
  59.  
  60. # Insert <P> at empty lines in selection, and in the beginning of the selection.
  61. # Several empty lines are contracted to one.
  62. proc htmlInsertParagraphs {} {
  63.     global HTMLmodeVars
  64.     if {![isSelection]} {
  65.         beep
  66.         message "No selection."
  67.         return
  68.     }
  69.     
  70.     set pIsContainer $HTMLmodeVars(pIsContainer)
  71.     
  72.     set oelem [htmlOpenElem P]
  73.     if {![string length $oelem]} {return}
  74.     
  75.     set text "¥r$oelem¥r"
  76.     set prevLineEmpty 1
  77.     
  78.     foreach ln [split [string trim [getSelect] "¥r"] "¥r"] {
  79.         regexp {[ ¥t]*} $ln lntest
  80.         # Only add <P> if previous line was not empty.
  81.         if {$ln == $lntest && !$prevLineEmpty} {
  82.             set prevLineEmpty 1
  83.             if {$pIsContainer} {
  84.                 append text "[htmlCloseElem P]¥r¥r$oelem¥r"
  85.             } else {
  86.                 append text "¥r$oelem¥r"
  87.             }
  88.         } else {
  89.             # Skip an empty line which follows another empty line.
  90.             if {$ln != $lntest} {
  91.                 set prevLineEmpty 0
  92.                 append text "$ln¥r"
  93.             }
  94.         }
  95.     }
  96.     if {$pIsContainer} {
  97.         append text "[htmlCloseElem P]¥r¥r"
  98.     }
  99.     
  100.     replaceText [getPos] [selEnd] $text
  101. }
  102.  
  103.  
  104. # Ask for input how to build a list. Returns "number of items" and
  105. # "ask for list item attributes". Returns "" if canceled or any problem.
  106. proc htmlListQuestions {ltype liattr lipr} {
  107.     global HTMLmodeVars
  108.     
  109.     set promptNoisily $HTMLmodeVars(promptNoisily)
  110.     if {[string length $liattr]} {
  111.         set optatts [htmlGetOptional $liattr]
  112.         set usedatts [htmlGetUsed $liattr]
  113.         set askForMore [htmlGetAttrMore $liattr]
  114.     } else {
  115.         set optatts ""
  116.         set askForMore [htmlGetAttrMore LI]
  117.         set usedatts [htmlGetUsed LI]
  118.     }
  119.     if {$lipr != "LI"} { 
  120.         set optatts [concat $optatts [htmlGetOptional DD]]
  121.         set usedatts [concat $usedatts [htmlGetUsed DD]]
  122.         if {!$askForMore} {set askForMore [htmlGetAttrMore DD]}
  123.     }
  124.     if {$HTMLmodeVars(useBigWindows)} {
  125.         set it {0 0 3 0}
  126.         while {1} {
  127.             set txt "dialog -w 280 -h 130 -b OK 20 100 75 120 -b Cancel 110 100 165 120 ¥
  128.             -t {$ltype list} 100 10 250 30 ¥
  129.             -t {How many items?} 10 40 150 60 -e [list [lindex $it 2]] 160 40 180 55"
  130.             if {[llength $optatts]} {
  131.                 append txt " -c {Ask for attributes for each $lipr} [lindex $it 3] ¥
  132.                 10 70 330 85"
  133.             }
  134.             set it [eval $txt]
  135.             if {[lindex $it 1]} {return}
  136.             set items [lindex $it 2]
  137.             if {[llength $it] == 4 && [lindex $it 3]} {
  138.                 set askForLiAttr 1
  139.             } else {
  140.                 set askForLiAttr 0
  141.             }
  142.             
  143.             if {![htmlIsUnsignedInteger $items] && $ltype != "DL"} {
  144.                 alertnote "Invalid input: non-negative integer required"
  145.             } elseif {![htmlIsPositiveInteger $items] && $ltype == "DL"} {
  146.                 alertnote "Invalid input: positive integer required"
  147.             } else {
  148.                 break
  149.             }
  150.         }
  151.     } else {
  152.         if {$promptNoisily} {beep}    
  153.         while {[catch {statusPrompt "$ltype list: How many items? " htmlNumberStatusFunc} items]} {
  154.             if {$items == "Cancel all!"} {message "Cancel"; return}
  155.         }
  156.         if {![htmlIsUnsignedInteger $items] && $ltype != "DL"} {
  157.             beep; message "Invalid input: non-negative integer required."; return
  158.         } elseif {![htmlIsPositiveInteger $items] && $ltype == "DL"} {
  159.             beep; message "Invalid input: positive integer required."; return
  160.         }
  161.         if {(([llength $optatts] && $askForMore) || [llength $usedatts]) && $items} {
  162.             if {$promptNoisily} {beep}    
  163.             while {[catch {statusPrompt "Ask for attributes for each $lipr? ¥[n¥] " ¥
  164.             htmlStatusAskYesOrNo} v]} {
  165.                 if {$v == "Cancel all!"} {message "Cancel"; return}
  166.             }
  167.             if {$v == "yes"} {
  168.                 set askForLiAttr 1
  169.             } else {
  170.                 set askForLiAttr 0
  171.             }
  172.         } else {
  173.             set askForLiAttr 0
  174.         }
  175.     }
  176.     return [list $items $askForLiAttr]
  177. }
  178.     
  179.  
  180. # Lists: Puts <cr>s before and after a list, inserts <li>, leaves the
  181. # insertion point there.  If anything is selected, makes it the first item.
  182. proc htmlBuildList {ltype {liattr ""} {listattr ""}} {
  183.     global HTMLmodeVars 
  184.     global htmlCurSel
  185.     global htmlIsSel
  186.     
  187.     set useTabMarks $HTMLmodeVars(useTabMarks)
  188.     set containers $HTMLmodeVars(lidtAreContainers)
  189.     
  190.     set listStr [htmlListQuestions $ltype $liattr LI]
  191.     if {![llength $listStr]} {
  192.         return
  193.     } else {
  194.         set items [lindex $listStr 0]
  195.         set askForLiAttr [lindex $listStr 1]
  196.     }
  197.  
  198.     # If zero list items, just make an htmlBuildCR2Elem
  199.     if {$items == 0} {
  200.         htmlBuildCR2Elem $ltype $listattr
  201.         return
  202.     }
  203.     
  204.     htmlGetSel
  205.     set sel $htmlCurSel
  206.     set IsSel $htmlIsSel
  207.     set text [htmlOpenCR 1]
  208.     if {$containers} {
  209.         set text1 "[htmlOpenElem $ltype $listattr]¥r"
  210.         if {$text1 == "¥r"} {return}
  211.         append text $text1
  212.         if {$askForLiAttr} {
  213.             set text1 [htmlOpenElem LI $liattr]
  214.         } else {
  215.             set text1 [htmlOpenElem LI NOATTR]
  216.         }
  217.         if {$text1 == ""} {return}
  218.         append text $text1
  219.         if {$IsSel} {    
  220.             append text "${sel}[htmlCloseElem LI]"
  221.             set currpos [expr [getPos] + [string length $text]]
  222.         } else {
  223.             set currpos [expr [getPos] + [string length $text]]
  224.             append text [htmlCloseElem LI]
  225.         }
  226.         for {set i 1} {$i < $items} {incr i} {
  227.             append text "¥r"
  228.             if {$askForLiAttr} {
  229.                 set text1 [htmlOpenElem LI $liattr]
  230.             } else {
  231.                 set text1 [htmlOpenElem LI NOATTR]
  232.             }
  233.             if {$text1 == ""} {return}
  234.             append text $text1
  235.             if {$i == 1 && $IsSel} {
  236.                 set currpos [expr [getPos] + [string length $text]]
  237.             } elseif {$useTabMarks} {
  238.                 append text "・"
  239.             }
  240.             append text [htmlCloseElem LI]
  241.         }
  242.     } else {
  243.         set text1 [htmlOpenElem $ltype $listattr]
  244.         if {$text1 == ""} {return}
  245.         append text $text1
  246.         append text "¥r"
  247.         if {$askForLiAttr} {
  248.             set text1 [htmlOpenElem LI $liattr]
  249.         } else {
  250.             set text1 [htmlOpenElem LI NOATTR]
  251.         }
  252.         if {$text1 == ""} {return}
  253.         append text $text1
  254.         if {$IsSel} {        
  255.             append text $sel 
  256.         } 
  257.         set currpos [expr [getPos] + [string length $text]]
  258.         for {set i 1} {$i < $items} {incr i} {
  259.             append text "¥r"
  260.             if {$askForLiAttr} {
  261.                 set text1 [htmlOpenElem LI $liattr]
  262.             } else {
  263.                 set text1 [htmlOpenElem LI NOATTR]
  264.             }
  265.             if {$text1 == ""} {return}
  266.             append text $text1
  267.             if {$useTabMarks} {append text "・"}
  268.         }
  269.     }
  270.     append text "¥r[htmlCloseElem $ltype]¥r¥r"
  271.     if {$useTabMarks} {append text "・"}
  272.     if {$IsSel} { deleteSelection }
  273.     
  274.     insertText $text
  275.     goto $currpos
  276. }
  277.  
  278.  
  279. # Add list entry.  If there is a selection, make it the entry.
  280.  
  281. proc htmlElemListEntry {liattr} {
  282.     global htmlCurSel htmlIsSel HTMLmodeVars
  283.     
  284.     set containers $HTMLmodeVars(lidtAreContainers)
  285.     set useTabMarks $HTMLmodeVars(useTabMarks)
  286.     htmlGetSel
  287.     set sel $htmlCurSel
  288.     set isSel $htmlIsSel
  289.     set text [htmlOpenCR]
  290.     set text1 [htmlOpenElem LI $liattr]
  291.     if {$text1 == ""} {return}
  292.     append text $text1
  293.     if {$isSel} { deleteSelection }
  294.     if {$containers} {
  295.         if {$isSel} { 
  296.             insertText $text "${sel}" [htmlCloseElem LI]
  297.         } else {
  298.             set currpos [expr [getPos] + [string length $text]]
  299.             append text [htmlCloseElem LI]
  300.             if {$useTabMarks} { append text "・"}
  301.             insertText $text
  302.             goto $currpos
  303.         }
  304.     } else {
  305.         insertText $text $sel
  306.     }
  307. }
  308.  
  309. # Make list items from selction.
  310. proc htmlMakeList {} {
  311.     global HTMLmodeVars
  312.     
  313.     set isContainer $HTMLmodeVars(lidtAreContainers)
  314.     
  315.     if {![isSelection]} {
  316.         beep
  317.         message "No selection."
  318.         return
  319.     }
  320.     
  321.     set values [dialog -w 220 -h 80 ¥
  322.     -t "Each item begins with:" 10 10 160 25 -e "*" 170 10 200 25 ¥
  323.     -b OK 20 45 85 65 -b Cancel 105 45 170 65]
  324.     
  325.     if {[lindex $values 2]} {return}
  326.     set itemStr [string trim [lindex $values 0]]
  327.     
  328.     if {![string length $itemStr]} {
  329.         beep
  330.         message "You must give a string which each item begins with."
  331.         return
  332.     }
  333.     set startPos [getPos]
  334.     set endPos [selEnd]
  335.     if {[catch {search -s -f 1 -i 0 -r 0 -m 0 $itemStr $startPos} res] || ¥
  336.     [lindex $res 1] > $endPos} {
  337.         beep 
  338.         message "No list item in selection."
  339.         return
  340.     }
  341.     # Check that the selections begins with a list item.
  342.     set preText [getText $startPos [lindex $res 0]]
  343.     regexp {[ ¥t¥r]*} $preText test
  344.     if {$test != $preText} {
  345.         beep
  346.         message "There is some text before the first list item."
  347.         return
  348.     }
  349.     # Get each list item.
  350.     set startPos [lindex $res 1]
  351.     while {![catch {search -s -f 1 -i 0 -r 0 -m 0 $itemStr $startPos} res2] && ¥
  352.     [lindex $res2 1] <= $endPos} {
  353.         set text2 [string trimleft [string trimright [getText $startPos [lindex $res2 0]] "¥r"]]
  354.         append text "¥r<[htmlSetCase LI]>$text2"
  355.         if {$isContainer} {append text [htmlCloseElem LI]}
  356.         set startPos [lindex $res2 1]
  357.     }
  358.     set text2 [string trimleft [string trimright [getText $startPos $endPos] "¥r"]]
  359.     append text "¥r<[htmlSetCase LI]>$text2"
  360.     if {$isContainer} {append text [htmlCloseElem LI]}
  361.     append text "¥r"
  362.     replaceText [getPos] [selEnd] [string trimleft $text "¥r"]
  363. }
  364.  
  365.  
  366. # Discursive Lists (term and description elems)
  367. #
  368. # The selection becomes the *description* (*not* the term)
  369.  
  370. # Build a discursive list
  371. proc htmlBuildDiscList {} {
  372.     global htmlCurSel
  373.     global htmlIsSel
  374.     global HTMLmodeVars 
  375.  
  376.     set containers $HTMLmodeVars(lidtAreContainers)
  377.     set useTabMarks    $HTMLmodeVars(useTabMarks)
  378.     
  379.     set listStr [htmlListQuestions DL DT "DT and DD"]
  380.     if {![llength $listStr]} {
  381.         return
  382.     } else {
  383.         set dlEntries [lindex $listStr 0]
  384.         set askForLiAttr [lindex $listStr 1]
  385.     }
  386.     if {$askForLiAttr} {
  387.         set liattr ""
  388.     } else {
  389.         set liattr NOATTR
  390.     }
  391.     
  392.     htmlGetSel
  393.     set Sel $htmlCurSel
  394.     set text [htmlOpenCR 1]
  395.     
  396.     if {$containers} {
  397.         set text1 "[htmlOpenElem DL]¥r"
  398.         if {$text1 == "¥r"} {return}
  399.         append text $text1
  400.         # the first entry
  401.         set text1 [htmlOpenElem DT $liattr]
  402.         if {$text1 == ""} {return}
  403.         append text $text1
  404.         set currpos [expr [getPos] + [string length $text]]
  405.         append text "[htmlCloseElem DT]¥t"
  406.         set text1 [htmlOpenElem DD $liattr]
  407.         if {$text1 == ""} {return}
  408.         append text $text1
  409.         if {$htmlIsSel} {
  410.             append text $Sel
  411.         } elseif {$useTabMarks} {
  412.             append text "・"
  413.         }
  414.         append text [htmlCloseElem DD]
  415.         # the rest of the entries
  416.         for {set i 1} {$i < $dlEntries} {incr i} {
  417.             append text "¥r"
  418.             set text1 [htmlOpenElem DT $liattr]
  419.             if {$text1 == ""} {return}
  420.             append text $text1
  421.             if {$useTabMarks} { append text "・" }
  422.             append text [htmlCloseElem DT] 
  423.             append text "¥t"
  424.             set text1 [htmlOpenElem DD $liattr]
  425.             if {$text1 == ""} {return}
  426.             append text $text1
  427.             if {$useTabMarks} { append text "・" }
  428.             append text [htmlCloseElem DD] 
  429.         }
  430.         
  431.         if {$useTabMarks} {append text "・"}
  432.         
  433.     } else {
  434.         set text1 [htmlOpenElem DL]
  435.         if {$text1 == ""} {return}
  436.         append text $text1
  437.         append text "¥r"
  438.  
  439.         # The first entry
  440.         set text1 [htmlOpenElem DT $liattr]
  441.         if {$text1 == ""} {return}
  442.         append text $text1
  443.     
  444.         set currpos [expr [getPos] + [string length $text]]
  445.         append text "¥t"
  446.         set text1 [htmlOpenElem DD $liattr]
  447.         if {$text1 == ""} {return}
  448.         append text $text1
  449.     
  450.         if {$htmlIsSel} {
  451.             append text $Sel
  452.         }
  453.         if {$useTabMarks} {append text "・"}        
  454.     
  455.         # Now for the rest of the entries
  456.         for {set i 1} {$i < $dlEntries} {incr i} {
  457.             append text "¥r"
  458.             set text1 [htmlOpenElem DT $liattr]
  459.             if {$text1 == ""} {return}
  460.             append text $text1
  461.             
  462.             if {$useTabMarks} {append text "・"}
  463.             append text "¥t"
  464.             set text1 [htmlOpenElem DD $liattr]
  465.             if {$text1 == ""} {return}
  466.             append text $text1
  467.         
  468.             if {$useTabMarks} {append text "・"}
  469.         }
  470.     }
  471.     append text "¥r[htmlCloseElem DL]¥r¥r"
  472.     if {$useTabMarks} {append text "・"}
  473.     if {$htmlIsSel} { deleteSelection }
  474.     insertText $text
  475.     goto $currpos
  476. }
  477.  
  478. # Add an individual entry to a discursive list
  479. proc htmlElemDiscEntry {} {
  480.     global htmlCurSel htmlIsSel
  481.     global HTMLmodeVars
  482.     set useTabMarks    $HTMLmodeVars(useTabMarks)
  483.     set containers $HTMLmodeVars(lidtAreContainers)
  484.     
  485.     htmlGetSel
  486.     set Sel $htmlCurSel
  487.     set text [htmlOpenCR]
  488.  
  489.     if {$containers} {
  490.         set text1 [htmlOpenElem DT]
  491.         if {$text1 == ""} {return}
  492.         append text $text1
  493.         set currpos [expr [getPos] + [string length $text]]
  494.         append text "[htmlCloseElem DT]¥t"
  495.         set text1 [htmlOpenElem DD]
  496.         if {$text1 == ""} {return}
  497.         append text $text1
  498.         if {$htmlIsSel} {
  499.             append text ${Sel}
  500.         } elseif {$useTabMarks} {append text "・"}
  501.         append text [htmlCloseElem DD]
  502.         if {$useTabMarks} {append text "・"}
  503.         if {$htmlIsSel} { deleteSelection }
  504.         insertText $text [htmlCloseCR]
  505.     } else {
  506.         set text1 [htmlOpenElem DT]    
  507.         if {$text1 == ""} {return}
  508.         append text $text1
  509.         set currpos [expr [getPos] + [string length $text]]
  510.         append text "¥t"
  511.         set text1 [htmlOpenElem DD]
  512.         if {$text1 == ""} {return}
  513.         append text $text1
  514.     
  515.         if {$htmlIsSel} {
  516.             append text $Sel
  517.         }
  518.         if {$useTabMarks} {append text "・"}
  519.         if {$htmlIsSel} { deleteSelection }
  520.         insertText $text [htmlCloseCR]
  521.     }
  522.     goto $currpos
  523. }
  524.  
  525.  
  526. # Different Input fields
  527.  
  528. proc htmlBuildInputElem {inputelem {cr1 0} {cr2 1}} {
  529.     htmlBuildOpening "INPUT TYPE=¥"${inputelem}¥"" $cr1 $cr2 $inputelem
  530. }
  531.  
  532.  
  533. # Table template. If there is any selection it is put in the first cell.
  534. proc htmlTableTemplate {} {
  535.     global htmlCurSel htmlIsSel HTMLmodeVars
  536.     
  537.     set useTabMarks $HTMLmodeVars(useTabMarks)
  538.     
  539.     set values {"" "" 0 0 0 0 "No value" "No value"}
  540.     set rows ""
  541.     set cols ""
  542.     set trAttrs [htmlGetChoices TR]
  543.     foreach w $trAttrs {
  544.         if {[string match "VALIGN=*" $w]} {
  545.             lappend valignMenu  [string range $w 7 end]
  546.         }    
  547.     }
  548.     foreach w $trAttrs {
  549.         if {[string match "ALIGN=*" $w]} {
  550.             lappend alignMenu  [string range $w 6 end]
  551.         }    
  552.     }
  553.     while {![htmlIsPositiveInteger $rows] || ![htmlIsPositiveInteger $cols]} {
  554.         
  555.         set box "-t {Table template} 50 10 200 25 ¥
  556.         -p 50 26 150 27 ¥
  557.         -t {Number of rows} 10 40 150 55  -e [list [lindex $values 0]] 160 40 180 55 ¥
  558.         -t {Number of columns} 10 65 150 80 -e [list [lindex $values 1]] 160 65 180 80 ¥
  559.         -c {Table headers in first row} [lindex $values 2] 10 90 250 105 ¥
  560.         -c {Table headers in first column} [lindex $values 3] 10 110 250 135 ¥
  561.         -t {Alignment for every row} 10 150 200 165 ¥
  562.         -b OK 20 230 85 250 -b Cancel 105 230 170 250"
  563.         
  564.         lappend box -t VALIGN= 10 175 70 190 ¥
  565.         -m [concat [list [lindex $values 6] "No value"] $valignMenu] 80 175 175 190 ¥
  566.         -t ALIGN= 10 200 60 215 ¥
  567.         -m [concat [list [lindex $values 7] "No value"] $alignMenu] 80 200 175 215 
  568.         set values [eval [concat dialog -w 230 -h 260 $box]]
  569.         
  570.         # Cancel?
  571.         if {[lindex $values 5] } {return}
  572.         
  573.         set rows [lindex $values 0]
  574.         set cols [lindex $values 1]
  575.         set THrow [lindex $values 2]
  576.         set THcol [lindex $values 3]
  577.         set valign [lindex $values 6]
  578.         set align [lindex $values 7]
  579.         
  580.         set trOpen "<[htmlSetCase TR]"
  581.         if {$valign != "No value"} {
  582.             append trOpen " " [htmlSetCase VALIGN=[htmlAddQuotes $valign]]
  583.         }
  584.         if {$align != "No value"} {
  585.             append trOpen " " [htmlSetCase ALIGN=[htmlAddQuotes $align]]
  586.         }
  587.         append trOpen ">"
  588.         if {![htmlIsPositiveInteger $rows] || ![htmlIsPositiveInteger $cols] } {
  589.             alertnote "The number of rows and columns must be specified."
  590.         }
  591.     }
  592.     
  593.     set tableOpen [htmlOpenElem TABLE]
  594.     if {![string length $tableOpen]} {return}
  595.     
  596.     htmlGetSel
  597.     if {$htmlIsSel} {deleteSelection}
  598.     
  599.     set text [htmlOpenCR 1]
  600.     append text "¥r" $tableOpen "¥r"
  601.     
  602.     for {set i 1} {$i <= $rows} {incr i} {
  603.         append text "¥r$trOpen¥r"
  604.         for {set j 1} {$j <= $cols} {incr j} {
  605.             # Put TH in first row or column?
  606.             if {$i == 1 && $THrow || $j == 1 && $THcol} {
  607.                 set cell [htmlSetCase TH]
  608.             } else {
  609.                 set cell [htmlSetCase TD]
  610.             }
  611.             append text "<$cell>"
  612.             if {$i == 1 && $j == 1} {
  613.                 if {$htmlIsSel} {
  614.                     append text $htmlCurSel
  615.                 } else {
  616.                     set curPos [expr [getPos] + [string length $text]]
  617.                 }
  618.             } elseif {$htmlIsSel && ( $i == 1 && $j == 2 || $i == 2 && $cols == 1 )} {
  619.                 set curPos [expr [getPos] + [string length $text]]
  620.             } elseif {$useTabMarks} {
  621.                 append text "・"
  622.             }    
  623.             append text [htmlCloseElem $cell]
  624.         }
  625.         append text "¥r[htmlCloseElem TR]¥r"
  626.     }
  627.     append text "¥r[htmlCloseElem TABLE]¥r¥r"
  628.     if {$useTabMarks && ($rows > 1 || $cols > 1 || !$htmlIsSel)} {append text "・"}
  629.     insertText $text
  630.     goto $curPos
  631. }
  632.  
  633.  
  634. # Take table rows in a selection and remove the TR, TD and TH elements and
  635. # put tabs between the elements.
  636. proc htmlrowsToTabs {} {
  637.     if {![isSelection]} {
  638.         beep
  639.         message "No selection."
  640.         return
  641.     }
  642.     
  643.     set startPos [getPos]
  644.     set endPos [selEnd]
  645.     if {[catch {search -s -f 1 -i 1 -r 1 -m 0 {<TR([ ¥t¥r]+[^>]*>|>)} $startPos} res] || ¥
  646.     [lindex $res 1] > $endPos} {
  647.         beep 
  648.         message "No table row in selection."
  649.         return
  650.     }
  651.     # Check that the selections begins with a table row.
  652.     set preText [getText $startPos [lindex $res 0]]
  653.     regexp {[ ¥t¥r]*} $preText test
  654.     if {$test != $preText} {
  655.         beep
  656.         message "First part of selection is not in a table row."
  657.         return
  658.     }
  659.     # Extract each table row.
  660.     set startPos [lindex $res 1]
  661.     while {![catch {search -s -f 1 -i 1 -r 1 -m 0 {<TR([ ¥t¥r]+[^>]*>|>)} $startPos} res2] && ¥
  662.     [lindex $res2 1] <= $endPos} {
  663.         set text2 [getText $startPos [lindex $res2 0]]
  664.         regsub -all "¥[¥t¥r¥]+" $text2 " " text2
  665.         append text [string trim $text2] "¥r"
  666.         set startPos [lindex $res2 1]
  667.     }
  668.     set text2 [getText $startPos $endPos]
  669.     regsub -all "¥[¥t¥r¥]+" $text2 " " text2
  670.     append text [string trim $text2]
  671.     
  672.     # Check that there is nothing after the last table row.
  673.     if {![catch {search -s -f 1 -i 1 -r 1 -m 0 {</TR>} $startPos} res] ¥
  674.     && [lindex $res 1] <= $endPos} {
  675.         set preText [getText [lindex $res 1] $endPos]
  676.         regexp {[ ¥t¥r]*} $preText test
  677.         if {$test != $preText} {
  678.             beep
  679.             message "Last part of selection not in a table row."
  680.             return
  681.         }
  682.     }
  683.     # Make the transformation.
  684.     foreach ln [split $text "¥r"] {
  685.         if {![string length $ln]} continue
  686.         regsub -all {> +<} $ln "><" ln
  687.         regsub -all {<(t|T)(h|H|d|D)([ ]+[^>]*>|>)} $ln "¥t" ln
  688.         regsub {    } $ln "" ln
  689.         regsub -all {</(t|T)(h|H|d|D|r|R)>} $ln "" ln
  690.         append out "$ln¥r"
  691.     }
  692.     replaceText [getPos] [selEnd] $out
  693. }
  694.  
  695. # Convert tab-delimited format to table rows.
  696. # First row and first coloumn can optionally consist of table headers.
  697. proc htmltabsToRows {} {
  698.     global HTMLmodeVars
  699.     
  700.     if {![isSelection]} {
  701.         beep
  702.         message "No selection."
  703.         return
  704.     }
  705.     
  706.     append oelem "¥r" [htmlOpenElem TR] "¥r"
  707.     if {$oelem == "¥r¥r"} {return}
  708.     
  709.     if {!$HTMLmodeVars(useBigWindows)} {
  710.         if {$HTMLmodeVars(promptNoisily)} {beep}
  711.         while {[catch {statusPrompt "Table headers in first row? ¥[n¥] " ¥
  712.         htmlStatusAskYesOrNo} v]} {
  713.             if {$v == "Cancel all!"} {message "Cancel"; return}
  714.         }
  715.         if {$v == "yes"} {
  716.             set THrow 1
  717.         } else {
  718.             set THrow 0
  719.         }
  720.         if {$HTMLmodeVars(promptNoisily)} {beep}
  721.         while {[catch {statusPrompt "Table headers in first column? ¥[n¥] " ¥
  722.         htmlStatusAskYesOrNo} v]} {
  723.             if {$v == "Cancel all!"} {message "Cancel"; return}
  724.         }            
  725.         if {$v == "yes"} {
  726.             set THcol 1
  727.         } else {
  728.             set THcol 0
  729.         }
  730.     } else {
  731.         set THbox [dialog -w 230  -h 105 -t "Put table headers in" 10 10 240 30 ¥
  732.         -c "first row" 0 10 40 100 60 -c "first column" 0 110 40 220 60 ¥
  733.         -b OK 20 75 85 95 -b Cancel 105 75 170 95]
  734.         if {[lindex $THbox 3]} {return}
  735.         set THrow [lindex $THbox 0]
  736.         set THcol [lindex $THbox 1]
  737.     }
  738.     
  739.     set out [htmlOpenCR]
  740.     set i 1
  741.     foreach ln [split [string trimright [getSelect] "¥r"] "¥r"] {
  742.         if {![string length $ln]} {
  743.             append out "$oelem[htmlCloseElem TR]¥r"
  744.         } else {
  745.             # Should there be headers in the first row?
  746.             if {$i == 1 && $THrow} {
  747.                 set cell TH
  748.             } else {
  749.                 set cell TD
  750.             }
  751.             # Should there be headers in the first column?
  752.             if {$THcol || ($i == 1 && $THrow)} {
  753.                 set fcell TH
  754.             } else {
  755.                 set fcell TD
  756.             }
  757.             regsub -all {    } $ln [htmlSetCase "</$cell><$cell>"] ln
  758.             if {$THcol} {
  759.                 regsub {[tT][dDhH]} $ln [htmlSetCase TH] ln
  760.             }
  761.             append out "$oelem<[htmlSetCase $fcell]>$ln"
  762.             # Add cell or fcell closing, depending on if there is more than one cell.
  763.             if {![regexp [htmlCloseElem $fcell] $ln]} {
  764.                 append out [htmlCloseElem $fcell]
  765.             } else {
  766.                 append out [htmlCloseElem $cell]
  767.             }
  768.             append out "¥r[htmlCloseElem TR]¥r"
  769.             incr i
  770.         }
  771.     }
  772.     replaceText [getPos] [selEnd] $out
  773. }
  774.  
  775.  
  776. proc htmlElemComment {} {
  777.     global htmlCurSel
  778.     global htmlIsSel
  779.     global HTMLmodeVars
  780.     set useTabMarks    $HTMLmodeVars(useTabMarks)
  781.     set commentPreString    $HTMLmodeVars(prefixString)
  782.     set commentSufString    $HTMLmodeVars(suffixString)
  783.  
  784.     htmlGetSel
  785.     if {$htmlIsSel} { deleteSelection }
  786.     set text "[htmlOpenCR]${commentPreString}$htmlCurSel"
  787.     set currpos [expr [getPos] + [string length $text]]
  788.     append text $commentSufString [htmlCloseCR]
  789.     if {!$htmlIsSel && $useTabMarks} {append text "・"}
  790.     insertText $text
  791.     if {!$htmlIsSel}    {
  792.         goto $currpos
  793.     }
  794. }
  795.  
  796.  
  797. #
  798. # Template for new file: HTML, TITLE, HEAD, BODY or FRAMESET
  799. # Optionally input BASE, LINK, ISINDEX, META and SCRIPT in HEAD.
  800. # We do not put in a DOCTYPE line.
  801. proc htmlNewTemplate {doctype} {
  802.     global htmlCurSel htmlIsSel HTMLmodeVars htmlHeadElements1 htmlHeadElements3 htmlPackageToUse
  803.     set useTabMarks    $HTMLmodeVars(useTabMarks)
  804.     set footers $HTMLmodeVars(footers)
  805.     set headelems [set htmlHeadElements$htmlPackageToUse]
  806.     
  807.     set bodyText ""
  808.     # If the window is not empty, either delete text or put it in the body.
  809.     if {![htmlIsEmptyFile]} {
  810.         set delBox [dialog -w 320 -h 90 -t "Nonempty window. Do you want to put the text¥
  811.         in the document's BODY, or delete it?" 10 10 310 50 ¥
  812.         -b "Put in BODY" 20 60 120 80 -b Delete 140 60 205 80 -b Cancel 225 60 290 80]
  813.         if {[lindex $delBox 1]} {
  814.             deleteText 0 [maxPos]
  815.         } elseif {[lindex $delBox 2]} {
  816.             return
  817.         } else {
  818.             set bodyText "[getText 0 [maxPos]]¥r"
  819.         }
  820.     } 
  821.     
  822.     if {$doctype == "FRAMESET"} {
  823.         set htxt "New document with frames"
  824.     } else {
  825.         set htxt "New document"
  826.     }
  827.     # Building footer menu.
  828.     foreach f $footers {
  829.         lappend foot [file tail $f]
  830.     }
  831.     set footmenu {"No footer"}
  832.     if {[info exists foot]} {
  833.         set footmenu [concat $footmenu $foot]
  834.     }
  835.     
  836.     set docTitle ""
  837.     set inHead {0 0 ""}
  838.     foreach elem $headelems {
  839.         lappend inHead 0
  840.     }
  841.     lappend inHead "No footer"
  842.     while {![string length $docTitle]} {
  843.         
  844.         # Construct the dialog box.
  845.         set box "-t [list $htxt] 100 10 300 25 -p 100 30 250 31 -t {TITLE} 10 40 60 55 ¥
  846.         -e [list [lindex $inHead 2]] 70 40 390 55 ¥
  847.         -t {Select the elements you want in the document¥'s HEAD} 10 70 390 85"
  848.         set hpos 100
  849.         set i 3
  850.         foreach elem $headelems {
  851.             append box " -c $elem [lindex $inHead $i] 10 $hpos 150 [expr $hpos + 15]"
  852.             incr hpos 20
  853.             incr i
  854.         }
  855.         incr hpos 10
  856.         append box " -t Footer 10 $hpos 80 [expr $hpos + 15] ¥
  857.         -m [list [concat [list [lindex $inHead $i]] $footmenu]] 90 $hpos 250 [expr $hpos + 15]"
  858.         incr hpos 30 
  859.         set inHead [eval [concat dialog -w 400 -h [expr $hpos + 30] ¥
  860.         -b OK 20 $hpos 85 [expr $hpos + 20] ¥
  861.         -b Cancel 110 $hpos 175 [expr $hpos + 20] $box]]
  862.         if {[lindex $inHead 1] } {return}
  863.         set docTitle [string trim [lindex $inHead 2]]
  864.         if {![string length $docTitle]} {
  865.             alertnote "A document title is required."
  866.         }
  867.     }
  868.     
  869.     
  870.     set text [htmlOpenElem HTML]
  871.     if {$text == ""} {return}
  872.     set text1 [htmlOpenElem HEAD]
  873.     if {$text1 == ""} {return}
  874.     append text "¥r¥r${text1}¥r¥r"
  875.     append text "[htmlOpenElem TITLE]${docTitle}[htmlCloseElem TITLE]¥r"
  876.     set hasScript 0
  877.     for {set i 0} {$i < [llength  $headelems]} {incr i} {
  878.         if {[lindex $inHead [expr $i + 3]]} {
  879.             set text1 [htmlOpenElem [lindex $headelems $i]]
  880.             if {$text1 != ""} {
  881.                 append text "¥r${text1}"
  882.                 if {[lindex $headelems $i] == "SCRIPT"} {
  883.                     append text "¥r"
  884.                     set currpos [string length $text]
  885.                     set hasScript 1
  886.                     append text "¥r[htmlCloseElem SCRIPT]"
  887.                 }
  888.             }
  889.         }
  890.     }
  891.     append text "¥r¥r[htmlCloseElem HEAD]¥r¥r"
  892.     
  893.     set text1 [htmlOpenElem $doctype]
  894.     if {$text1 == ""} {return}
  895.     append text "$text1¥r¥r"
  896.     append text $bodyText
  897.     if {!$hasScript} {
  898.         set currpos [string length $text]
  899.     } elseif {$useTabMarks} {
  900.         append text "・"
  901.     }    
  902.     
  903.     # Insert footer.
  904.     set footval [lindex $inHead [expr [llength $headelems] + 3]]
  905.     if {$footval != "No footer"} {
  906.         set footerFile [lindex $footers [lsearch -exact $foot $footval]]
  907.         if {![catch {readFile $footerFile} footText]} {
  908.             append text "¥r¥r$footText"
  909.         } else {
  910.             alertnote "Could not read footer, $footerFile"
  911.         }
  912.     }
  913.     append text "¥r¥r[htmlCloseElem $doctype]¥r¥r[htmlCloseElem HTML]"
  914.     if {![htmlIsEmptyFile]} {deleteText 0 [maxPos]}
  915.     insertText $text
  916.  
  917.     goto $currpos
  918. }
  919.